<template>
  <div class="home" :style="{height: `${winHeight}px`}">
    <div class="home-container-left">
      <el-tabs tab-position="left" :style="{height: `${winHeight}px`}">
		  
        <el-tab-pane label="表结构">
          <div class="tree-container" :style="{height: `${winHeight}px`}">
            <div v-for="(table,index) in treeData" :key="table.tname" class="tree-table">
              <div class="tree-table-name" @click="onFoldTable(index)" @dblclick="onDblclick(table)">
                <span class="tree-fold-btn" 
                    :class="['tree-fold-btn', foldIndex.includes(index) ? 'el-icon-remove-outline' : 'el-icon-circle-plus-outline']" 
                />
                <img src="@/assets/table.png" width="15px">
                {{ table.tname }}
              </div>
              <template v-if="table.fields.length > 0 && foldIndex.includes(index)">
                <div v-for="field in table.fields" :key="field.name" class="tree-table-field">
                  {{ field.COLUMN_NAME }}
                  <!-- <span class="el-icon-document-copy"></span> -->
                </div>
              </template>
            </div>
          </div>
        </el-tab-pane>
		
		
		<el-tab-pane label="API服务">
		  <ul class="order-list">
		    <li v-for="item in apiList" :key="item.id" @click="copyApiSQLOrder(item.apiDefination,item.id)">
		      <img src="@/assets/api.png">
		      {{ item.resourceName }}
		    </li>
		  </ul>
		</el-tab-pane>
		
		
        <el-tab-pane label="命令集" @click="changeTalbe(3)">
          <ul class="order-list">
            <li v-for="item in commitsList" :key="item.createTime" @click="copySQLOrder(item)">
              <img src="@/assets/order.png">
              {{ item.title }}
            </li>
          </ul>
        </el-tab-pane>
      </el-tabs>
    </div>
    <div class="home-contaioner-right">
		<div>
			<div>
					<span>&nbsp;&nbsp;&nbsp;&nbsp;数据库密钥：<input   id="datasourceId" name="datasourceId" v-model="datasourceId" /></span>
					<span>&nbsp;&nbsp;&nbsp;&nbsp;用户key：<input  id="userId" name="userId" v-model="userId" /></span>
					<span><button @click="queryTables()">加载工作区</button></span>
			</div>
			
		</div>
      <!-- SQL编辑器 -->
      <codemirror-editor
        ref="codemirrorEditor"
        :run-loading="runLoading"
        @input="onEditorInput"
        @run="onSQLRun"
        @stop="onSQLStop"
        @commit="onSQLCommit"
		@createApi="oncreateApi"
      ></codemirror-editor>
	  
	  <div style="width: 100%;"><span>参数:</span><span ><input id="paramValue" v-model="paramValue"  style="width: 600px;"name="paramValue"/></span></div>
	  
      <div class="tables-result" :style="{height: `${tablesHeight}px`}">
        <el-tabs type="border-card" style="height: 99%">
          <el-tab-pane label="信息">
            <span v-if="runType === 0" class="el-icon-info" style="color: #909399;"></span>
            <span v-if="runType === 1" class="el-icon-success" style="color: #67C23A;"></span>
            <span v-if="runType === 2" class="el-icon-warning" style="color: #E6A23C;"></span>
            <span v-if="runType === 3" class="el-icon-error" style="color: #F56C6C;"></span>
            {{ runResult }}
            <template v-if="runType === 3">
              <div class="error-message"><b>message：</b>{{ errMsg.affectedRows }}</div>
              <div class="error-message"><b>errno：</b>{{ errMsg.exception }}</div>
              <div class="error-message"><b>sql：</b>"{{ errMsg.resultCode }}"</div>
              <div class="error-message"><b>code：</b>{{ errMsg.columnNames }}</div>
           
            </template>
          </el-tab-pane>
          <el-tab-pane label="结果">
            <el-table
              :data="tableData"
              border
              :style="{width: '100%', height: `${tablesHeight - 80}px`}">
              <el-table-column
                v-for="item in columns"
                :key="item.value"
                :prop="item.value"
                :label="item.label"
              />
            </el-table>
          </el-tab-pane>
		  <el-tab-pane label="JSON数据">
		    <json-viewer :value="jsonInfo" copyable ></json-viewer>
		  </el-tab-pane>
		  
		  <el-tab-pane label="API接口使用说明">
			  <div >
				  <div style="margin-bottom: 20px;">
				  				接口地址（支持https请求）：  <span style="color:blue;">http://www.nangs.vip/shejiqi/sjq/data/customerApi</span>
				  </div>
				  <div style="margin-bottom: 20px;">
				  				  sql： {{this.apiInfo.apiDefination}}
				  </div>
				  <div style="margin-bottom: 20px;">
				  				  创建时间：{{this.apiInfo.createTime}}
				  </div>
				  <div>
				  					  使用说明：
				  </div>
				  <div>
					
					 <span>
						  ApiCode:<label style="color: red;">{{this.apiInfo.apiCode}}</label><br/>
						  param: <label style="color: blue;">如果sql中没有设置动态传参，则填写默认的值：{}，否则需填写：{参数名1:value,参数名2:value2}</label><br/>
						  rowType: <label>出参类型：row 或者  list</label><br/>
						 
						  
					 </span>
				  </div>
				  <div><el-button ><a href="http://47.122.16.230:9091/wiki/doc/TPNHSQJZA" target="_blank">试一试</a></el-button></div>
				  
				  
			  </div>
		    
		  </el-tab-pane>
		  
        </el-tabs>
      </div>
    </div>
  </div>
</template>

<script>
import CodemirrorEditor from '@/components/CodemirrorEditor'
import {  mapGetters, mapActions } from 'vuex'
import JsonViewer from 'vue-json-viewer'
export default {
  name: 'Home',
  components: {
    CodemirrorEditor,
	JsonViewer
  },
  data() {
    return {
      winHeight: 0,
      tablesHeight: 0,
      foldIndex: [], // 记录展开状态的表结构，存入index
      treeData: [], // 左侧展示的表结构
      runResult: '暂无数据', // 运行结果提示
	  jsonInfo: '',//json数据
      runType: 0, // 运行结果类型，0无结果、1成功、2警告、3异常
      tableData: [], // 运行结果的表数据展示
      columns: [], // 运行的表结构，对象元素，{label: '', value: ''}
      code: '', // 实时输入的代码
      runLoading: false, // 运行加载状态
	  datasourceId: '945dd54beb374beba4a0e9528ab572a4',//数据源
	  userId: 'common&1',//用户Id
	  apiList: [],//用户定义的API服务列表
	  apiId: 0,//临时存储API的ID值
	  paramValue: '{}',//默认参数
	  apiInfo:{
		  apiCode: '',
		  apiDefination: '',
		  createTime: '',
		  updateTime: ''
	  },
      errMsg: {
        affectedRows: '',
		exception: '',
		resultCode: '',
		columnNames: '',
		sqlState: ''
      }
    }
  },
  created() {
    this.queryTables()
  },
  mounted() {
    this.winHeight = window.innerHeight - 52
    this.tablesHeight = window.innerHeight - 392
    window.onresize = () => {
      this.winHeight = window.innerHeight - 52
      this.tablesHeight = window.innerHeight - 392
    }
  },
  computed: {
    ...mapGetters([
      'db',
      'commitsList'
    ])
  },
  methods: {
    ...mapActions('dbs', [
      'createDatabase',
      'execute'
    ]),
    ...mapActions('commits', [
      'addLogs'
    ]),
    ...mapActions('http', [
      'getTreeData',
      'getFieldNames',
      'sendSQL',
	  'getApiList',
	  'createApi'
    ]),
    onFoldTable(index) {
		this.apiId=0;
      // 表结构折叠事件
      const i = this.foldIndex.indexOf(index)
      if (i === -1) {
        this.foldIndex.push(index)
      } else {
        this.foldIndex.splice(i,1)
      }
    },
	onDblclick(tableName){
		//双击表名
		this.apiId=0;
		const tname = tableName.tname;
		 this.$refs.codemirrorEditor.setValue(this.code+tname );
		
	},
	
    copySQLOrder(item) {
      // 复制命令
      this.$refs.codemirrorEditor.setValue(item.sql)
	   this.apiId=0
	  
    },
	copyApiSQLOrder(item,id) {
	  // 复制命令
	  this.$refs.codemirrorEditor.setValue(item)
	  //改变API服务的ID值
	  this.apiId = id;
	  
	  //加载API使用说明
	   
	    this.apiList.forEach(api => {
		
			
			if(id === api.id){
				this.apiInfo=api
			}
	   }) 
	  
	  
	},
    onEditorInput(code) {
      // 编辑器输入事件
      this.code = code
    },
    onSQLRun() {
      // SQL编辑器运行事件
      this.executeSql()
    },
    onSQLStop() {
      // SQL编辑器停止运行事件
	   this.$refs.codemirrorEditor.setValue('')
    },
	oncreateApi(){
		// SQL编辑器生成API服务
		if (this.code.trim() === '') {
		  this.$message.warning('请先编辑 SQL 命令！')
		  return
		}
		this.$prompt('请输入API服务名称：', '提示', {
		  confirmButtonText: '确定',
		  cancelButtonText: '取消',
		  inputValidator: (val) => {
		    if (val.trim() === '') {
		      return false
		    }
		    return true
		  },
		  inputErrorMessage: '命令标题不能为空'
		}).then(({ value }) => {
		  if (value.trim() !== '') {
		    const api = {
		      apiName: value,
		      sql: this.code,
		      datasourceId: this.datasourceId,
			  userId: this.userId
		    }
			
		  this.createApiInfo(api)
		 
		   // this.$message.success('提交成功！')
		  } else {
		    this.$message.error('提交失败！')
		  }
		}).catch(() => {
		  this.$message.warning('已取消提交')
		})
	},
    onSQLCommit() {
      // SQL编辑器提交事件
      if (this.code.trim() === '') {
        this.$message.warning('请先编辑 SQL 命令！')
        return
      }
      this.$prompt('请输入命令标题：', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputValidator: (val) => {
          if (val.trim() === '') {
            return false
          }
          return true
        },
        inputErrorMessage: '命令标题不能为空'
      }).then(({ value }) => {
        if (value.trim() !== '') {
          const logs = {
            title: value,
            sql: this.code,
            createTime: Date.now()
          }
          this.addLogs(logs)
          this.$message.success('提交成功！')
        } else {
          this.$message.error('提交失败！')
        }
      }).catch(() => {
        this.$message.warning('已取消提交')
      })
    },
	async createApiInfo(api){
		 api.id=this.apiId;
		 const res = await this.createApi(api);
		 const code =res.code;
		 const data =res.data;
		 if(code ===1){
			 this.$message.success('提交成功！')
			 //刷新API服务列表
			 this.apiList=null;
			 const result = await this.getApiList({datasourceId: this.datasourceId,userId: this.userId})
			 const code1 = result.code;
			 const data1 = result.data;
			 if(code1 === 1){
			 	this.apiList = data1;
			 }
		 }else{
			 this.$message.error('提交失败！'+res.msg)
		 }
		 
	},
    async executeSql() {
		debugger
      // 执行SQL语句
      if (this.code.trim() === '') {
        this.$message.warning('请先编辑 SQL 命令！')
        return
      }
      this.runLoading = true
      this.tableData = []
      this.columns = []
      this.runResult = '执行中...'
      this.runType = 0
      this.errMsg = {}
	  const start =new Date();
      const res = await this.sendSQL({datasourceId: this.datasourceId, sql: this.code,param:this.paramValue })
	
	  debugger
     // const { code, data } = res
	 const code =res.code;
	
	    if(code === -1){
			 this.runResult = `查询失败！`+res.msg;
			  this.errMsg = {...res.data}
			 return;
		}
	 const data = res.data.rows;
      if (this.code.startsWith('SELECT') || this.code.startsWith('select')) {
		   const end =new Date();
		   const dif =end -start;
        if (code === 1) {
          this.runType = 1 
          this.runResult = `成功查询 ${data.length} 条数据，`+'耗时：'+dif+'毫秒'
		  this.jsonInfo = JSON.stringify(res)
		  debugger
          if (data.length > 0) {
            this.tableData = [...data]
            const obj = { ...this.tableData[0] }
            for(let key in obj) {
              this.columns.push({
                label: key,
                value: key
              })
            }
          }
        } else if (code === -1) {
          this.runType = 3
          this.runResult = '执行失败！'
          this.errMsg = {...res.data}
        }
      } else {
        if (code === 1) {
		  if(res.data.affectedRows === -1){
			   this.runType = 3
			   this.runResult = `执行失败！`
			   this.errMsg = {...res.data}
		  }else{
			  this.runType = 1
			  this.runResult = `执行成功！`
			  this.queryTables()
		  }
          
          
        } else if (code === -1) {
          this.runType = 3
          this.runResult = '执行失败！'
          this.errMsg = {...res.data}
        }
      }
      this.runLoading = false
    },
    async queryTables() {
      // 查询所有表
	  const result = await this.getApiList({datasourceId: this.datasourceId,userId: this.userId})
	  console.log(result.data)
	  const code1 = result.code;
	  const data1 = result.data;
	  if(code1 === 1){
		  this.apiList = data1;
	  }
	  
      const res = await this.getTreeData({datasourceId: this.datasourceId,userId: this.userId})
	  
	  
     // const { code, data } = res
	 const code =res.code;
	 debugger
	 console.log(res)
	 const data = res.data.rows;
      if (code == 1 && data!=null && data.length > 0) {
        this.treeData = []
        const tips = {}
        data.forEach(async(tname) => {
          if (tname.table_name && tname.table_name.trim() != '') {
            const treeObj = {
              tname: tname.table_name,
              fields: []
            }
            tips[tname.table_name] = []
            // 查询表中的字段
            const fieldRes = await this.getFieldNames({datasourceId: this.datasourceId,tname: tname.table_name })
			debugger
            if (fieldRes.code === 1) {
              treeObj.fields = [...fieldRes.data.rows]
              fieldRes.data.rows.forEach(f => {
                tips[tname.table_name].push(f.COLUMN_NAME)
              })
            }
            this.treeData.push(treeObj)
          }
        })
        this.$refs.codemirrorEditor.setHintOptions(tips)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.home {
  background-color: #F4F4F4;
  display: flex;

  // 左侧区域
  .home-container-left {
    flex: 1.1;
    height: 100%;
    background-color: #fff;

    .el-tabs {
      user-select: none;
      & ::v-deep .el-tabs__item {
        font-size: 12px;
        padding: 0px 10px;
      }

      .tree-container {
        overflow-y: scroll;
        overflow-x: hidden;

        .tree-table {
          font-size: 12px;
          box-sizing: border-box;
          padding: 0px 10px;

          .tree-table-name {
            line-height: 30px;
            display: flex;
            align-items: center;
            cursor: pointer;

            .tree-fold-btn {
              font-size: 14px;
              color: #666;
              display: inline-block;
              height: 10px;
              padding: 0px 4px;
              margin-right: 5px;
              cursor: pointer;
            }
          }

          .tree-table-field {
            line-height: 30px;
            box-sizing: border-box;
            padding-left: 30px;
            color: #777;
            display: flex;
            align-items: center;

            .el-icon-document-copy {
              margin-left: 5px;
              cursor: pointer;

              &:hover {
                color: #409EFF;
              }
            }
          }
        }
      }
      .tree-container::-webkit-scrollbar {
        width: 3px;
      }
      .tree-container::-webkit-scrollbar-thumb {
        border-radius: 10px;
        -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
        background: rgba(0, 0, 0, 0.1);
      }

      // 命令集
      .order-list {
        list-style: none;
        padding: 0;
        margin: 0;

        li {
          font-size: 12px;
          margin: 10px 0px;
          box-sizing: border-box;
          padding: 5px 15px;
          cursor: pointer;
          display: flex;
          align-items: center;

          &:hover {
            background: #E8F2FF;
          }

          img {
            width: 22px;
            margin-right: 5px;
          }
        }
      }
    }
  }

  // 右侧区域
  .home-contaioner-right {
    flex: 6;
    height: 100%;

    // 工具栏
    .header-tools {
      height: 40px;
  
      .tools-list {
        list-style: none;
        padding: 0  0 0 20px;
        margin: 0;
        display: flex;
        align-items: center;
        height: 100%;
        font-size: 12px;
        color: #666;
  
        .tools-item {
          margin: 0px 10px;
          cursor: pointer;
  
          &:hover {
            color: #999;
          }
  
          .el-icon-video-play {
            color: #4BC451;
          }
          .el-icon-video-pause {
            color: #F35353;
          }
          .el-icon-document-checked,.el-icon-s-promotion,.el-icon-document {
            color: #4381E6;
          }
        }
      }
    }

    // 运行结果
    .tables-result {
      width: 100%;
      box-sizing: border-box;
      padding: 5px 0 0 1px;

      .el-tabs {
        .el-tab-pane {
          font-size: 12px;
          
          .error-message {
            margin: 8px 0px;
            box-sizing: border-box;
            padding-left: 14px;
          }
        }

        .el-table {
          // border: 1px solid red;
          height: 100px;
          overflow-y: scroll;
          font-size: 12px;
        }
        .el-table::-webkit-scrollbar {
          width: 5px;
        }
        .el-table::-webkit-scrollbar-thumb {
          border-radius: 10px;
          -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
          background: rgba(0, 0, 0, 0.2);
        }
      }
    }
  }

}
</style>
